#ifndef CCEMATERIALEFFECTEDITORDIALOG_H
#define CCEMATERIALEFFECTEDITORDIALOG_H


#include <qdialog.h>
#include <material/materialeditor.h>
#include <ui_effecteditorwidget.h>
#include <material/materialmanager.h>
#include <material/materialview.h>


class cceMaterialEffectStageItem;
class cceMaterialProgramSlotItem;
class cceMaterialProgramItem;
class cceMaterialEffectPrimaryItem : public cceMaterialPrimaryItem
{
  Q_OBJECT
protected:
  void AddTechnique ();

public:
  cceMaterialEffectPrimaryItem ();

  void MoveEffectStage(cceMaterialEffectStageItem* stage, int direction);

  cceMaterialEffectStageItem* AddStageItem ();
  void RemoveStage (cceMaterialEffectStageItem* stage);

  unsigned GetNumberOfStages () const;
  cceMaterialEffectStageItem* GetStage(unsigned idx);


signals:
	void Changed ();
  void ShowEditor (cceMaterialItem* item);
};


class cceMaterialEffectStageItem : public cceMaterialTechniqueItem
{
  Q_OBJECT
private:
  cceMaterialEffectPrimaryItem	*_primary;

  cceMaterialProgramItem*         _programs[Pass_COUNT];
  cceMaterialProgramSlotItem*     _slots[Pass_COUNT];

  void RemoveAll ();
  void UpdateAll ();

protected:
  virtual void RemoveTechnique ();
  virtual void MoveUp ();
  virtual void MoveDown ();

public:
  cceMaterialEffectStageItem (cceMaterialEffectPrimaryItem* primary);

  cceMaterialProgramItem* GetProgram (cceMaterialPass pass);

	void ChangeProgram (cceMaterialPass pass, cceMaterialProgram* program);
  cceMaterialProgramItem* SetProgram (cceMaterialPass pass, cceMaterialProgram* program);
  void RemoveProgram (cceMaterialPass pass);

signals:
	void Changed ();
  void ShowEditor (cceMaterialItem* item);
};

class cceMaterialProgramSlotItem : public cceMaterialSlotItem
{
private:
  cceMaterialEffectStageItem* _stage;
  cceMaterialPass _pass;


protected:
  void dragEnterEvent (QGraphicsSceneDragDropEvent* evt);
  void dropEvent (QGraphicsSceneDragDropEvent* evt);

public:
  cceMaterialProgramSlotItem (cceMaterialEffectStageItem* stage, cceMaterialPass pass);

};

class cceMaterialProgramItem : public cceMaterialValueItem
{
  Q_OBJECT
private:
  cceMaterialEffectStageItem* _stage;

  cceMaterialProgram* _program;
  cceMaterialPass _pass;


private slots:
  void onProgramChanged ();

protected:
	void dragEnterEvent (QGraphicsSceneDragDropEvent* evt);
	void dropEvent (QGraphicsSceneDragDropEvent* evt);

protected slots:
  void RemoveValue ();
  void ProgramClicked ();

public:
  cceMaterialProgramItem (cceMaterialEffectStageItem* stage, cceMaterialProgram* program, cceMaterialPass pass);

  cceMaterialProgram* GetProgram ();
  bool IsProgram (cceMaterialProgram* program);

signals:
  void ShowEditor (cceMaterialItem* item);
};


class cceMaterialEffect;
class cceMaterialEffectEditorDialog : public cceMaterialEditorAbstract
{
  Q_OBJECT
private:
  Ui::MaterialEffectEditorWidget	_gui;

  cceMaterialView									*_effectEditorView;

  cceMaterialEffect               *_effect;
  cceMaterialEffectPrimaryItem		*_primaryItem;

private:
	bool UpdateEffectFromGUI ();
	void UpdateGUIFromEffect ();

  bool EffectChanged ();
	void Close ();

private slots:
  void ForceClose ();
	void Changed ();
  void on_lineEditName_textChanged (const QString& name);

public:
  cceMaterialEffectEditorDialog(QWidget* parent);

  virtual QString GetName () const;
  virtual bool Save ();

  void SetEffect (cceMaterialEffect* effect);
};

#endif // CCEMATERIALEFFECTEDITORDIALOG_H
